home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / tsmorph32s.lha / TSM32s.lha / OpalLoad.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-06  |  47.5 KB  |  1,579 lines

  1. // TSMorph - Amiga Morphing program
  2. // Copyright (C) © 1993  Topicsave Limited
  3.  
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // any later version.
  8.  
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13.  
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. // mpaddock@cix.compulink.co.uk
  19.  
  20. // Include precompiled headers if required
  21. #ifndef TSMORPH_H
  22. #include "TSMorph.h"
  23. #endif
  24.  
  25. #include "JPEG_LS/jinclude.h"
  26.  
  27. extern UWORD FileFormat = 0;    // Format of file being loaded
  28.  
  29. /* Loads an image (in various formats)
  30.  * pic     : pointer to Picture structure
  31.  * filename: filename to load
  32.  * Returns : TRUE if loaded OK
  33.  */
  34. BOOL
  35. MyLoadBrush (struct Picture *pic,UBYTE *filename) {
  36.     BOOL OpenILBM = FALSE;    // Are we loading a (<24 plane) ILBM
  37.     char *e = NULL;            // First
  38.     char *e1 = NULL;            // and second part of error message
  39.     long hnum;                    // Help number
  40.     long err;                    // Error flag
  41.     BPTR fh;                        // File handle
  42.     UBYTE buffer[5]="\0\0\0\0";    // First 4 bytes of file for identification
  43.  
  44.     // Try and open file and read 1st 4 bytes
  45.     if (fh = Open(filename,MODE_OLDFILE)) {
  46.         FRead(fh,buffer,4,1);
  47.         // check if a sort of IFF file
  48.         if (!strcmp(buffer,"LIST") ||
  49.              !strcmp(buffer,"CAT ") ||
  50.              !strcmp(buffer,"FORM")) {
  51.             FileFormat = FORMAT_IFF;
  52.         }
  53.         else {
  54.             // check if a JFIF JPEG
  55.             if ((buffer[0] == 0xFF) &&
  56.                  (buffer[1] == 0xD8)) {
  57.                 FileFormat = FORMAT_JPEG;
  58.             }
  59.             else {
  60.                 // check if a GIF
  61.                 if ((buffer[0] == 'G') &&
  62.                      (buffer[1] == 'I') &&
  63.                      (buffer[2] == 'F')) {
  64.                     FileFormat = FORMAT_GIF;
  65.                 }
  66.                 else {
  67.                     // check if a PPM
  68.                     if ((buffer[0] == 'P') &&
  69.                          ((buffer[1] == '2') ||
  70.                           (buffer[1] == '3') ||
  71.                           (buffer[1] == '5') ||
  72.                           (buffer[1] == '6'))) {
  73.                         FileFormat = FORMAT_PPM;
  74.                     }
  75.                     else {
  76.                         // Otherwise default to TARGA (the only other format we load)
  77.                         FileFormat = FORMAT_TARGA;
  78.                     }
  79.                 }
  80.             }
  81.         }
  82.         Close(fh);
  83.     }
  84.     else {
  85.         // error file not found
  86.         FileFormat = 0;
  87.         e = "File does not exist '%s'";
  88.         hnum = HE_NoFile;
  89.         e1 = filename;
  90.     }
  91.     // If the file is and IFF and we only open ILBMs in some cases then perform some checks
  92.     if ((FileFormat == FORMAT_IFF) && ((OpenMode == OPEN_ILBM_IF_ILBM) || (OpenMode == OPEN_ILBM_IF_COLOURS))) {
  93.         if (pic->ilbm->ParseInfo.iff = AllocIFF()) {
  94.             err = queryilbm(pic->ilbm,filename);
  95.             if (!err) {
  96.                 if (OpenMode == OPEN_ILBM_IF_COLOURS) {
  97.                     // if we only open if screen colours then check depth
  98.                     if (!(pic->ilbm->Bmhd.nPlanes > TSMorphWnd->WScreen->BitMap.Depth)) {
  99.                         OpenILBM = TRUE;
  100.                     }
  101.                 }
  102.                 else {    // OpenMode == OPEN_ILBM_IF_ILBM
  103.                     // if open if an ILBM then check < 24 bits
  104.                     if (pic->ilbm->Bmhd.nPlanes < 24) {
  105.                         OpenILBM = TRUE;
  106.                     }
  107.                 }
  108.             }
  109.             FreeIFF(pic->ilbm->ParseInfo.iff);
  110.             pic->ilbm->ParseInfo.iff = NULL;
  111.         }
  112.         else {
  113.             e = "Unable to AllocIFF";
  114.             hnum = HE_AllocIFF;
  115.         }
  116.     }
  117.     // If we always open ILBM or the above checks out OK then try and open
  118.     if (!EGS && (OpenILBM || ((OpenMode == OPEN_ILBM_ALWAYS) && !e))) {
  119.         if (pic->ilbm->ParseInfo.iff = AllocIFF()) {
  120.             // set up IFF stuff and load image
  121.             pic->ilbm->ParseInfo.propchks = props;
  122.             pic->ilbm->ParseInfo.collectchks = nowt;
  123.             pic->ilbm->ParseInfo.stopchks = stops;
  124.             if (loadbrush(pic->ilbm,filename)) {
  125.                 closeifile(&(pic->ilbm->ParseInfo));
  126.                 e = "Failure loading Image '%s'";
  127.                 e1 = filename;
  128.                 hnum = HE_LoadImage;
  129.             }
  130.             else {
  131.                 closeifile(&(pic->ilbm->ParseInfo));
  132.                 FreeIFF(pic->ilbm->ParseInfo.iff);
  133.                 pic->ilbm->ParseInfo.iff = NULL;
  134.                 return TRUE;
  135.             }
  136.         }
  137.         else {
  138.             e = "Unable to AllocIFF";
  139.             hnum = HE_AllocIFF;
  140.         }
  141.     }
  142.     else {
  143.         // otherwise try and load using another format
  144.         if (!e) {
  145.             return OpalLoad(pic,filename);
  146.         }
  147.     }
  148.     Error(e,"OK",e1,hnum);
  149.     return FALSE;
  150. }
  151.  
  152. /* Loads an image (in various formats)
  153.  * pic     : pointer to Picture structure
  154.  * filename: filename to load
  155.  * Returns : TRUE if loaded OK
  156.  */
  157. BOOL OpalLoad(struct Picture *pic,UBYTE *filename) {
  158.     char                     *e        = NULL;    // Error message main text
  159.     char                    *e1     = NULL;    // sub text,
  160.     long                     Err;                // OpalError
  161.     ULONG                    hnum;                // Help on error
  162.     struct OpalScreen    *OScrn;            // OpalScreen
  163.     UBYTE                    *p[3]= {NULL,NULL,NULL};    // rbg planes
  164.     UBYTE r[256],g[256],b[256];        // rgb colors of screen (8 bit)
  165.     ULONG                 col[4];            // Table for get RGB32
  166.     UWORD                    i,j;                // loop counters
  167.     UBYTE                    *plane;            // EGB bit map byte pointer
  168.     UWORD                 color;            // Colour
  169.     UBYTE *red,*green,*blue;            // rgb pointers
  170.     UWORD                    maxcol;            // Number of colors
  171.     UWORD xadd;                                // bytes to add to get to next line
  172.     decompress_info_ptr info;            // Load JPEG stuff
  173.     BOOL                    ReMap = FALSE;    // Have to remap ourselves
  174.     struct RastPort    Rp;                // Rast port for conversion
  175.     struct DCTVCvtHandle    *handle=NULL;    // DCTV conversion stuff
  176.     UWORD                    *DCTVcolors;    // DCTV palette
  177.  
  178.     OpenProgressWindow();        // Open the progress window
  179.     if (ProgressWnd) {
  180.          GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  181.                               GTTX_Text,(ULONG)"Creating Colormap",
  182.                              TAG_END);
  183.         HandleProgressIDCMP();
  184.     }
  185.     // Store and set up to 256 colours
  186.       maxcol = min((1 << TSMorphWnd->WScreen->BitMap.Depth),256);
  187.     if (GfxBase->lib_Version > 38) {
  188.         for (i=0; i < maxcol; ++i) {
  189.             GetRGB32(TSMorphWnd->WScreen->ViewPort.ColorMap,i,1,col);
  190.             r[i]=(col[0]>>24);
  191.             g[i]=(col[1]>>24);
  192.             b[i]=(col[2]>>24);
  193.         }
  194.     }
  195.     else {
  196.         for (i=0; i < maxcol; ++i) {
  197.             color = GetRGB4(TSMorphWnd->WScreen->ViewPort.ColorMap,i);
  198.             r[i]=((color&0x0f00)>>4)|((color&0x0f00)>>8);
  199.             g[i]=(color&0x00f0)|((color&0x00f0)>>4);
  200.             b[i]=((color&0x000f)<<4)|(color&0x000f);
  201.         }
  202.     }
  203.     // If we are not opening OPAL and the file is IFF
  204.     if ((OpenMode != OPEN_OPAL) &&
  205.          (FileFormat == FORMAT_IFF)) {
  206.         // try and load IFF
  207.         if (pic->ilbm->ParseInfo.iff = AllocIFF()) {
  208.             pic->ilbm->ParseInfo.propchks = props;
  209.             pic->ilbm->ParseInfo.collectchks = nowt;
  210.             pic->ilbm->ParseInfo.stopchks = stops;
  211.             if (ProgressWnd) {
  212.                  GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  213.                                       GTTX_Text,(ULONG)"Loading ILBM",
  214.                                      TAG_END);
  215.                 HandleProgressIDCMP();
  216.             }
  217.             if (loadbrush(pic->ilbm,filename)) {
  218.                 closeifile(&(pic->ilbm->ParseInfo));
  219.                 e = "Failure loading Image '%s'";
  220.                 e1 = filename;
  221.                 hnum = HE_LoadImage;
  222.             }
  223.             else {
  224.                 closeifile(&(pic->ilbm->ParseInfo));
  225.                 if (pic->ilbm->Bmhd.nPlanes == 24) {
  226.                     // 24 bit image - free colours
  227.                     freecolors(pic->ilbm);
  228.                     if (ProgressWnd) {
  229.                          GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  230.                                               GTTX_Text,(ULONG)"Converting 24 bit to Chunky",
  231.                                              TAG_END);
  232.                         HandleProgressIDCMP();
  233.                     }
  234.                     // Allocate Chunky planes
  235.                     if ((p[0] = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),0)) &&
  236.                          (p[1] = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),0)) &&
  237.                        (p[2] = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),0))) {
  238.                       // Convert to chunky RGB
  239.                       if (InitArray(pic->ilbm->Bmhd.w) && PlanarToChunky(pic,pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,p[0],p[1],p[2])) {
  240.                           // Bytes to add to get to next row
  241.                             xadd = (((pic->ilbm->Bmhd.w+15)>>4)<<4) - pic->ilbm->Bmhd.w;
  242.                             red = p[0];
  243.                             blue = p[2];
  244.                             green = p[1];
  245.                                 if (EGS) {
  246.                                     // Convert to an EGS BitMap
  247.                                 if (pic->EGS_BitMap = E_AllocBitMap(pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,24,E_PIXELMAP,E_EB_NOTSWAPABLE,NULL)) {
  248.                                     plane = ((struct E_EBitMapFull *)(pic->EGS_BitMap))->Typekey.PixelMap.Planes.Dest;
  249.                                     if (ProgressWnd) {
  250.                                          GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  251.                                                               GTTX_Text,(ULONG)"Converting to EGS",
  252.                                                              TAG_END);
  253.                                         HandleProgressIDCMP();
  254.                                     }
  255.                                     for (i = 0; i<pic->ilbm->Bmhd.h; i++) {
  256.                                         for (j = 0; j<pic->ilbm->Bmhd.w; j++) {
  257.                                             *plane++ = *red++;
  258.                                             *plane++ = *green++;
  259.                                             *plane++ = *blue++;
  260.                                             plane++;
  261.                                         }
  262.                                         plane += (pic->EGS_BitMap->BytesPerRow - (4*pic->ilbm->Bmhd.w));
  263.                                         red += xadd;
  264.                                         green += xadd;
  265.                                         blue += xadd;
  266.                                     }
  267.                                     // Free everything and return ok
  268.                                     FreeArray();
  269.                                     FreeVec(p[0]);
  270.                                     FreeVec(p[1]);
  271.                                     FreeVec(p[2]);
  272.                                     CloseProgressWindow();
  273.                                     pic->width = pic->ilbm->Bmhd.w;
  274.                                     pic->height = pic->ilbm->Bmhd.h;
  275.                                     return TRUE;
  276.                                 }
  277.                                 else {
  278.                                     e = "Unable to allocate memory for bitmap";
  279.                                     hnum = HE_AllocPlanes;
  280.                                 }
  281.                                 }
  282.                                 else {
  283.                                 if (ProgressWnd) {
  284.                                     GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  285.                                                               GTTX_Text,(ULONG)"Remapping 24 bit palette",
  286.                                                            TAG_END);
  287.                                     GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  288.                                                          GTSL_Level,0,
  289.                                                            GTSL_Max,pic->ilbm->Bmhd.h-1,TAG_END);
  290.                                     HandleProgressIDCMP();
  291.                                     }
  292.                                   // Convert to screen palette using 020 if present
  293.                                 if (((struct ExecBase *)SysBase)->AttnFlags & AFF_68020) {
  294.                                     RGBToScreen020(red,green,blue,pic->ilbm->Bmhd.h,pic->ilbm->Bmhd.w,maxcol,xadd,r,g,b);
  295.                                 }
  296.                                  else {
  297.                                     RGBToScreen000(red,green,blue,pic->ilbm->Bmhd.h,pic->ilbm->Bmhd.w,maxcol,xadd,r,g,b);
  298.                                 }
  299.                                 if (ProgressWnd) {
  300.                                      GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  301.                                                             GTTX_Text,(ULONG)"Converting 24 bit to Planar",
  302.                                                            TAG_END);
  303.                                     HandleProgressIDCMP();
  304.                                 }
  305.                                 // Convert back to planar
  306.                                 if (ChunkyToPlanar(pic,pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,p[0])) {
  307.                                     // Free everything and return ok
  308.                                     FreeArray();
  309.                                     FreeVec(p[0]);
  310.                                     FreeVec(p[1]);
  311.                                     FreeVec(p[2]);
  312.                                     CloseProgressWindow();
  313.                                     return TRUE;
  314.                                 }
  315.                                 // Free everything
  316.                                 else {
  317.                                     e = "Unable to allocate memory for bitmap";
  318.                                     hnum = HE_AllocPlanes;
  319.                                 }
  320.                             }
  321.                         }
  322.                         else {
  323.                             e = "Unable to allocate memory for bitmap";
  324.                             hnum = HE_AllocPlanes;
  325.                         }
  326.                         FreeArray();
  327.                     }
  328.                     else {
  329.                         e = "Unable to allocate memory for bitmap";
  330.                         hnum = HE_AllocPlanes;
  331.                     }
  332.                     if (p[0]) FreeVec(p[0]);
  333.                     if (p[1]) FreeVec(p[1]);
  334.                     if (p[2]) FreeVec(p[2]);
  335.                 }
  336.                 else {
  337.                     // not a 24 bit image
  338.                     // If we have dctv.library then check if a DCTV image
  339.                     if (DCTVBase && TestDCTVSignature(pic->ilbm->brbitmap)) {
  340.                         if (ProgressWnd) {
  341.                              GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  342.                                                   GTTX_Text,(ULONG)"Converting DCTV to Chunky",
  343.                                                  TAG_END);
  344.                             HandleProgressIDCMP();
  345.                         }
  346.                         // Allocate and set up DCTV palette
  347.                         if (DCTVcolors = AllocVec(2L<<pic->ilbm->Bmhd.nPlanes,NULL)) {
  348.                             for (i=0; i < (1L<<pic->ilbm->Bmhd.nPlanes); ++i) {
  349.                                 DCTVcolors[i] = ((pic->ilbm->RGB[i*4+1] & 0xf0) << 4) |
  350.                                                      ((pic->ilbm->RGB[i*4+2] & 0xf0)) |
  351.                                                      ((pic->ilbm->RGB[i*4+3] & 0xf0) >> 4);
  352.                             }
  353.                             // Allocate RGB chunky planes and DCTV stuff
  354.                             if ((p[0] = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),0)) &&
  355.                                  (p[1] = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),0)) &&
  356.                                  (p[2] = AllocVec(((((pic->ilbm->Bmhd.w+15)>>4)<<4)*pic->ilbm->Bmhd.h),0)) &&
  357.                                  (InitArray(pic->ilbm->Bmhd.w)) &&
  358.                                  (handle = AllocDCTVCvtTags(pic->ilbm->brbitmap,
  359.                                                     DCTVCVTA_Type, DCTVCVTT_DCTVtoRGB,
  360.                                                     DCTVCVTA_Width, (((pic->ilbm->Bmhd.w+15)>>4)<<4),
  361.                                                     DCTVCVTA_Height, pic->ilbm->Bmhd.h,
  362.                                                     DCTVCVTA_Flags, ((pic->ilbm->camg & LACE)?DCTVCVTF_Lace:0)|
  363.                                                                         DCTVCVTF_CustomRGBBuf,
  364.                                                     DCTVCVTA_ColorTable, DCTVcolors,
  365.                                                     TAG_END))) {
  366.                                 handle->Red = p[0];
  367.                                 handle->Green = p[1];
  368.                                 handle->Blue = p[2];
  369.                                 if (ProgressWnd) {
  370.                                     GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  371.                                                         GTSL_Level,0,
  372.                                                          GTSL_Max,pic->ilbm->Bmhd.h-1,TAG_END);
  373.                                     GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass1],ProgressWnd,NULL,
  374.                                                      GTSL_Level,1,
  375.                                                       GTSL_Max,EGS?1:2,TAG_END);
  376.                                     HandleProgressIDCMP();
  377.                                 }
  378.                                 // use dctv.library to convert to chunky
  379.                                 while (handle->DstLineNum < handle->Height) {
  380.                                     CvtDCTVLine(handle);
  381.                                     if ((handle->DstLineNum > 0) &&
  382.                                          (handle->DstLineNum <= handle->Height)) {
  383.                                         if (ProgressWnd) {
  384.                                                GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  385.                                                         GTSL_Level,handle->DstLineNum-1,
  386.                                                         TAG_END);
  387.                                             HandleProgressIDCMP();
  388.                                         }
  389.                                         handle->Red += (((pic->ilbm->Bmhd.w+15)>>4)<<4);
  390.                                         handle->Green += (((pic->ilbm->Bmhd.w+15)>>4)<<4);
  391.                                         handle->Blue += (((pic->ilbm->Bmhd.w+15)>>4)<<4);
  392.                                     }
  393.                                 }
  394.                                 red = p[0];
  395.                                 blue = p[2];
  396.                                 green = p[1];
  397.                                     if (EGS) {
  398.                                         // Convert to an EGS BitMap
  399.                                     if (pic->EGS_BitMap = E_AllocBitMap(pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,24,E_PIXELMAP,E_EB_NOTSWAPABLE,NULL)) {
  400.                                         plane = ((struct E_EBitMapFull *)(pic->EGS_BitMap))->Typekey.PixelMap.Planes.Dest;
  401.                                         if (ProgressWnd) {
  402.                                              GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  403.                                                                   GTTX_Text,(ULONG)"Converting to EGS",
  404.                                                                  TAG_END);
  405.                                             HandleProgressIDCMP();
  406.                                         }
  407.                                         xadd = (((pic->ilbm->Bmhd.w+15)>>4)<<4) - pic->ilbm->Bmhd.w;
  408.                                         for (i = 0; i<pic->ilbm->Bmhd.h; i++) {
  409.                                             for (j = 0; j<pic->ilbm->Bmhd.w; j++) {
  410.                                                 *plane++ = *red++;
  411.                                                 *plane++ = *green++;
  412.                                                 *plane++ = *blue++;
  413.                                                 plane++;
  414.                                             }
  415.                                             plane += (pic->EGS_BitMap->BytesPerRow - (4*pic->ilbm->Bmhd.w));
  416.                                             red += xadd;
  417.                                             green += xadd;
  418.                                             blue += xadd;
  419.                                         }
  420.                                         FreeVec(DCTVcolors);
  421.                                         freecolors(pic->ilbm);
  422.                                         FreeArray();
  423.                                         FreeVec(p[0]);
  424.                                         FreeVec(p[1]);
  425.                                         FreeVec(p[2]);
  426.                                         CloseProgressWindow();
  427.                                         FreeDCTVCvt(handle);
  428.                                         pic->width = pic->ilbm->Bmhd.w;
  429.                                         pic->height = pic->ilbm->Bmhd.h;
  430.                                         return TRUE;
  431.                                     }
  432.                                     else {
  433.                                         e = "Unable to allocate memory for bitmap";
  434.                                         hnum = HE_AllocPlanes;
  435.                                     }
  436.                                 }
  437.                                 else {
  438.                                     if (ProgressWnd) {
  439.                                         GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  440.                                                               GTTX_Text,(ULONG)"Remapping DCTV palette",
  441.                                                            TAG_END);
  442.                                         GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass1],ProgressWnd,NULL,
  443.                                                          GTSL_Level,2,
  444.                                                            TAG_END);
  445.                                      GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  446.                                                             GTSL_Level,0,
  447.                                                            TAG_END);
  448.                                       }
  449.                                       // convert to screen palette and then to planar (see above)
  450.                                     xadd = (((pic->ilbm->Bmhd.w+15)>>4)<<4) - pic->ilbm->Bmhd.w;
  451.                                     if (((struct ExecBase *)SysBase)->AttnFlags & AFF_68020) {
  452.                                         RGBToScreen020(red,green,blue,pic->ilbm->Bmhd.h,pic->ilbm->Bmhd.w,maxcol,xadd,r,g,b);
  453.                                     }
  454.                                      else {
  455.                                         RGBToScreen000(red,green,blue,pic->ilbm->Bmhd.h,pic->ilbm->Bmhd.w,maxcol,xadd,r,g,b);
  456.                                     }
  457.                                     if (ProgressWnd) {
  458.                                          GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  459.                                                               GTTX_Text,(ULONG)"Converting to Planar",
  460.                                                                TAG_END);
  461.                                         HandleProgressIDCMP();
  462.                                     }
  463.                                     if (ChunkyToPlanar(pic,pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,p[0])) {
  464.                                         FreeVec(DCTVcolors);
  465.                                         freecolors(pic->ilbm);
  466.                                         FreeArray();
  467.                                         FreeVec(p[0]);
  468.                                         FreeVec(p[1]);
  469.                                         FreeVec(p[2]);
  470.                                         CloseProgressWindow();
  471.                                         FreeDCTVCvt(handle);
  472.                                         return TRUE;
  473.                                     }
  474.                                     else {
  475.                                         e = "Unable to allocate memory for bitmap";
  476.                                         hnum = HE_AllocPlanes;
  477.                                     }
  478.                                 }
  479.                             }
  480.                             else {
  481.                                 e = "Unable to allocate memory for bitmap";
  482.                                 hnum = HE_AllocPlanes;
  483.                             }
  484.                             FreeArray();
  485.                             if (handle) {
  486.                                 FreeDCTVCvt(handle);
  487.                             }
  488.                             if (p[0]) FreeVec(p[0]);
  489.                             if (p[1]) FreeVec(p[1]);
  490.                             if (p[2]) FreeVec(p[2]);
  491.                         }
  492.                         else {
  493.                             e = "Unable to allocate memory for bitmap";
  494.                             hnum = HE_AllocPlanes;
  495.                         }
  496.                         FreeVec(DCTVcolors);
  497.                     }
  498.                     else {
  499.                         // not 24 bit and not DCTV
  500.                         // Convert image planar to screen palette planar (using 020+ if present)
  501.                         if (InitArray(pic->ilbm->Bmhd.w)) {
  502.                             if (ProgressWnd) {
  503.                               GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  504.                                                          GTSL_Max,pic->ilbm->Bmhd.h-1,TAG_END);
  505.                                 HandleProgressIDCMP();
  506.                             }
  507.                             InitRastPort(&Rp);
  508.                             Rp.BitMap = pic->ilbm->brbitmap;
  509.                             maxcol = min(maxcol,1<<pic->ilbm->Bmhd.nPlanes);
  510.                             if (EGS) {
  511.                                   // Convert to an EGS BitMap
  512.                                 if (pic->EGS_BitMap = E_AllocBitMap(pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,24,E_PIXELMAP,E_EB_NOTSWAPABLE,NULL)) {
  513.                                     plane = ((struct E_EBitMapFull *)(pic->EGS_BitMap))->Typekey.PixelMap.Planes.Dest;
  514.                                     if (ProgressWnd) {
  515.                                          GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  516.                                                               GTTX_Text,(ULONG)"Converting to EGS",
  517.                                                              TAG_END);
  518.                                         HandleProgressIDCMP();
  519.                                     }
  520.                                     if (((struct ExecBase *)SysBase)->AttnFlags & AFF_68020) {
  521.                                         PaletteToEGS020(&Rp,pic,plane,r,g,b);
  522.                                     }
  523.                                      else {
  524.                                         PaletteToEGS000(&Rp,pic,plane,r,g,b);
  525.                                     }
  526.                                     // and clean up
  527.                                     FreeArray();
  528.                                     freecolors(pic->ilbm);
  529.                                     CloseProgressWindow();
  530.                                     pic->width = pic->ilbm->Bmhd.w;
  531.                                     pic->height = pic->ilbm->Bmhd.h;
  532.                                     return TRUE;
  533.                                 }
  534.                                 else {
  535.                                     e = "Unable to allocate memory for bitmap";
  536.                                     hnum = HE_AllocPlanes;
  537.                                 }
  538.                             }
  539.                             else {
  540.                                 if (((struct ExecBase *)SysBase)->AttnFlags & AFF_68020) {
  541.                                     PaletteToScreen020(&Rp,pic,maxcol,r,g,b);
  542.                                 }
  543.                                  else {
  544.                                     PaletteToScreen000(&Rp,pic,maxcol,r,g,b);
  545.                                 }
  546.                                 // and clean up
  547.                                 FreeArray();
  548.                                 freecolors(pic->ilbm);
  549.                                 CloseProgressWindow();
  550.                                 return TRUE;
  551.                             }
  552.                         }
  553.                         else {
  554.                             e = "Unable to allocate memory for bitmap";
  555.                             hnum = HE_AllocPlanes;
  556.                         }
  557.                     }
  558.                 }
  559.             }
  560.         }
  561.         else {
  562.             e = "Unable to AllocIFF";
  563.             hnum = HE_AllocIFF;
  564.         }
  565.     }
  566.     // If we are not opening OPAL and the file is not IFF
  567.    if ((OpenMode != OPEN_OPAL) &&
  568.          (FileFormat != FORMAT_IFF)) {
  569.        // if the screen is < 8 colours or we do not allow palette changes or image is not JPEG then
  570.        // we will remap later. Otherwise the JPEG code will code will use its own palette
  571.         if ((TSMorphWnd->WScreen->BitMap.Depth < 3) || (FileFormat != FORMAT_JPEG) ||
  572.             (!PaletteAllowed)) {
  573.             ReMap = TRUE;
  574.         }
  575.         if (ProgressWnd) {
  576.            GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  577.                                   GTTX_Text,
  578.                                   (FileFormat == FORMAT_JPEG)?(ULONG)"Loading JFIF":
  579.                                   (FileFormat == FORMAT_GIF)?(ULONG)"Loading GIF":
  580.                                   (FileFormat == FORMAT_PPM)?(ULONG)"Loading PPM":
  581.                                   (FileFormat == FORMAT_TARGA)?(ULONG)"Loading Targa?":
  582.                                   (ULONG)"Loading ?",
  583.                                 TAG_END);
  584.             HandleProgressIDCMP();
  585.         }
  586.         // try and Load image (JFIF,GIF,PPM,TARGA)
  587.         if ((info = LoadJPEG(filename,ReMap|EGS?0:min(1<<TSMorphWnd->WScreen->BitMap.Depth,256),r,g,b,&(p[0]))) &&
  588.             ((info->output_file) || (p[0] && p[1] && p[2]))) {
  589.            if (info->output_file) {
  590.                p[0] = (UBYTE *)info->output_file;
  591.                p[1] = p[0] + (((info->image_width+15)>>4)<<4) * info->image_height;
  592.                p[2] = p[1] + (((info->image_width+15)>>4)<<4) * info->image_height;
  593.            }
  594.            if (EGS) {
  595.                 xadd = (((info->image_width+15)>>4)<<4) - info->image_width;
  596.                 // Convert to an EGS BitMap
  597.                 if (pic->EGS_BitMap = E_AllocBitMap(info->image_width,info->image_height,24,E_PIXELMAP,E_EB_NOTSWAPABLE,NULL)) {
  598.                     red = p[0];
  599.                     blue = p[2];
  600.                     green = p[1];
  601.                     plane = ((struct E_EBitMapFull *)(pic->EGS_BitMap))->Typekey.PixelMap.Planes.Dest;
  602.                     if (ProgressWnd) {
  603.                          GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  604.                                                  GTTX_Text,(ULONG)"Converting to EGS",
  605.                                              TAG_END);
  606.                         HandleProgressIDCMP();
  607.                     }
  608.                     for (i = 0; i<info->image_height; i++) {
  609.                         for (j = 0; j<info->image_width; j++) {
  610.                             *plane++ = *red++;
  611.                             *plane++ = *green++;
  612.                             *plane++ = *blue++;
  613.                             plane++;
  614.                         }
  615.                         plane += (pic->EGS_BitMap->BytesPerRow - (4*info->image_width));
  616.                         red += xadd;
  617.                         green += xadd;
  618.                         blue += xadd;
  619.                     }
  620.                     FreeVec(p[0]);
  621.                     CloseProgressWindow();
  622.                     pic->width = info->image_width;
  623.                     pic->height = info->image_height;
  624.                     return TRUE;
  625.                 }
  626.                 else {
  627.                     e = "Unable to allocate memory for bitmap";
  628.                     hnum = HE_AllocPlanes;
  629.                 }
  630.             }
  631.             else {
  632.                 // Allocate BitMap
  633.                 if (ProgressWnd) {
  634.                    GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  635.                                           GTTX_Text,(ULONG)"Allocating Bitmap",
  636.                                         TAG_END);
  637.                     HandleProgressIDCMP();
  638.                 }
  639.                 pic->ilbm->Bmhd.nPlanes = min(TSMorphWnd->WScreen->BitMap.Depth,8);
  640.                 pic->ilbm->Bmhd.w = info->image_width;
  641.                 pic->ilbm->Bmhd.h = info->image_height;
  642.                 if (InitArray(pic->ilbm->Bmhd.w) && (pic->ilbm->brbitmap = AllocMem(sizeof(struct BitMap),MEMF_CLEAR))) {
  643.                     InitBitMap(pic->ilbm->brbitmap,pic->ilbm->Bmhd.nPlanes,info->image_width,info->image_height);
  644.                     for (i=0;
  645.                         (i < pic->ilbm->Bmhd.nPlanes) && !e;            // Allow up to 8 bitplanes
  646.                         ++i) {
  647.                         if (!(pic->ilbm->brbitmap->Planes[i] = AllocRaster(pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h))) {
  648.                             e = "Unable to allocate memory for bitmap";
  649.                             hnum = HE_AllocPlanes;
  650.                         }
  651.                     }
  652.                 }
  653.                 else {
  654.                     e = "Unable to allocate memory for bitmap";
  655.                     hnum = HE_AllocPlanes;
  656.                 }
  657.                 if (!e) {
  658.                     if (ProgressWnd) {
  659.                        GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  660.                                               GTTX_Text,(ULONG)"Converting to Planar",
  661.                                             TAG_END);
  662.                         HandleProgressIDCMP();
  663.                      }
  664.                      // Remap the RGB image to screen palette if required (see above)
  665.                      if (ReMap) {
  666.                         xadd = (((info->image_width+15)>>4)<<4) - info->image_width;
  667.                         red = p[0];
  668.                         blue = p[2];
  669.                         green = p[1];
  670.                         if (ProgressWnd) {
  671.                             GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  672.                                                    GTTX_Text,(ULONG)"Remapping palette",
  673.                                                   TAG_END);
  674.                             GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  675.                                                  GTSL_Level,0,
  676.                                                   GTSL_Max,info->image_height-1,TAG_END);
  677.                             HandleProgressIDCMP();
  678.                          }
  679.                         if (((struct ExecBase *)SysBase)->AttnFlags & AFF_68020) {
  680.                             RGBToScreen020(red,green,blue,info->image_height,info->image_width,maxcol,xadd,r,g,b);
  681.                         }
  682.                          else {
  683.                             RGBToScreen000(red,green,blue,info->image_height,info->image_width,maxcol,xadd,r,g,b);
  684.                         }
  685.                     }
  686.                     if (ProgressWnd) {
  687.                          GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  688.                                                 GTTX_Text,(ULONG)"Converting to Planar",
  689.                                                TAG_END);
  690.                         HandleProgressIDCMP();
  691.                     }
  692.                     // Then convert back to planar
  693.                     if (ChunkyToPlanar(pic,info->image_width,info->image_height,p[0])) {
  694.                         if (!ReMap) {
  695.                             // not remapping so reformat JPEGs palette to our format
  696.                             if (ProgressWnd) {
  697.                                GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  698.                                                       GTTX_Text,(ULONG)"Creating Colormap",
  699.                                                     TAG_END);
  700.                                 HandleProgressIDCMP();
  701.                             }
  702.                             if (pic->ilbm->colortable = (Color4 *)AllocMem(min(1<<TSMorphWnd->WScreen->BitMap.Depth,256)*sizeof(Color4),NULL)) {
  703.                                 pic->ilbm->ncolors = min(1<<TSMorphWnd->WScreen->BitMap.Depth,256);
  704.                                 pic->ilbm->ctabsize = pic->ilbm->ncolors*sizeof(Color4);
  705.                                 for (i = 0;
  706.                                      i < pic->ilbm->ncolors;
  707.                                      ++i) {
  708.                                     pic->ilbm->colortable[i] = ((r[i] & 0xf0) << 4) | (g[i] & 0xf0) | (b[i] >> 4);
  709.                                 }
  710.                             }
  711.                         }
  712.                         // Free everything and return OK
  713.                         FreeArray();
  714.                         FreeVec(p[0]);
  715.                         CloseProgressWindow();
  716.                         return TRUE;
  717.                     }
  718.                     else {
  719.                         e = "Unable to allocate memory for bitmap";
  720.                         hnum = HE_AllocPlanes;
  721.                     }
  722.                     // Free everything
  723.                 }
  724.                 FreeArray();
  725.                 if (pic->ilbm->brbitmap) {
  726.                     for (i = 0;
  727.                           (i < pic->ilbm->Bmhd.nPlanes);            // Allow up to 8 bitplanes
  728.                           ++i) {
  729.                         if (!(pic->ilbm->brbitmap->Planes[i])) {
  730.                             FreeRaster(pic->ilbm->brbitmap->Planes[i],pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h);
  731.                             pic->ilbm->brbitmap->Planes[i] = NULL;
  732.                         }
  733.                     }
  734.                     FreeMem(pic->ilbm->brbitmap,sizeof(struct BitMap));
  735.                     pic->ilbm->brbitmap = NULL;
  736.                 }
  737.             }
  738.             FreeVec(p[0]);
  739.         }
  740.     }
  741.     // If we have not hit a fatal error yet, and opal.library is available then try it
  742.     if (!e && OpalBase) {
  743.         if (ProgressWnd) {
  744.              GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  745.                                  GTTX_Text,(ULONG)"Loading using opal.library",
  746.                                 TAG_END);
  747.             HandleProgressIDCMP();
  748.         }
  749.         Err = LoadImage24(NULL,filename,VIRTUALSCREEN24|FORCE24);
  750.         if (Err < OL_ERR_MAXERR) {
  751.             switch (Err) {
  752.             case OL_ERR_OUTOFMEM:
  753.                 e = "Failure - Out of memory - loading '%s'";
  754.                 break;
  755.             case OL_ERR_OPENFILE:
  756.                 e = "Failure - Opening file - loading '%s'";
  757.                 break;
  758.             case OL_ERR_FORMATUNKNOWN:
  759.                 e = "Failure - Unknown Format - loading '%s'";
  760.                 break;
  761.             case OL_ERR_NOTILBM:
  762.                 e = "Failure - Not an ILBM file - loading '%s'";
  763.                 break;
  764.             case OL_ERR_FILEREAD:
  765.                 e = "Failure - Reading file - loading '%s'";
  766.                 break;
  767.             case OL_ERR_BADIFF:
  768.                 e = "Failure - Bad IFF Format - loading '%s'";
  769.                 break;
  770.             case OL_ERR_CANTCLOSE:
  771.                 e = "Failure - Can not Close - loading '%s'";
  772.                 break;
  773.             case OL_ERR_BADJPEG:
  774.                 e = "Failure - Bad JPEG Format - loading '%s'";
  775.                 break;
  776.             case OL_ERR_UNSUPPORTED:
  777.                 e = "Failure - Unsupported Format - loading '%s'";
  778.                 break;
  779.             case OL_ERR_CTRLC:
  780.             case OL_ERR_NOTHUMBNAIL:
  781.             case OL_ERR_OPENSCREEN:
  782.             case OL_ERR_FILEWRITE:
  783.             default:
  784.                 e = "Failure - Unknown problem - loading '%s'";
  785.                 break;
  786.             }
  787.             e1 = filename;
  788.             hnum = HE_OpalVision;
  789.         }
  790.         else {
  791.             if (ProgressWnd) {
  792.                  GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  793.                                      GTTX_Text,(ULONG)"Converting to RGB",
  794.                                     TAG_END);
  795.                 HandleProgressIDCMP();
  796.             }
  797.             OScrn = (struct OpalScreen *)Err;
  798.             // Allocate chunky bit maps
  799.             if ((p[0] = AllocVec(((((OScrn->Width+15)>>4)<<4)*OScrn->Height),0)) &&
  800.                  (p[1] = AllocVec(((((OScrn->Width+15)>>4)<<4)*OScrn->Height),0)) &&
  801.                  (p[2] = AllocVec(((((OScrn->Width+15)>>4)<<4)*OScrn->Height),0))) {
  802.                 // Convert Opal vision screen to RGB
  803.                  OVtoRGB(OScrn,p,0,0,((OScrn->Width+15)>>4)<<4,OScrn->Height);
  804.                 if (EGS) {
  805.                     red = p[0];
  806.                     blue = p[2];
  807.                     green = p[1];
  808.                     // Convert to an EGS BitMap
  809.                     if (pic->EGS_BitMap = E_AllocBitMap(OScrn->Width,OScrn->Height,24,E_PIXELMAP,E_EB_NOTSWAPABLE,NULL)) {
  810.                         plane = ((struct E_EBitMapFull *)(pic->EGS_BitMap))->Typekey.PixelMap.Planes.Dest;
  811.                         if (ProgressWnd) {
  812.                              GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  813.                                                   GTTX_Text,(ULONG)"Converting to EGS",
  814.                                                  TAG_END);
  815.                             HandleProgressIDCMP();
  816.                         }
  817.                         xadd = (((OScrn->Width+15)>>4)<<4) - OScrn->Width;
  818.                         for (i = 0; i<OScrn->Height; i++) {
  819.                             for (j = 0; j<OScrn->Width; j++) {
  820.                                 *plane++ = *red++;
  821.                                 *plane++ = *green++;
  822.                                 *plane++ = *blue++;
  823.                                 plane++;
  824.                             }
  825.                             plane += (pic->EGS_BitMap->BytesPerRow - (4*OScrn->Width));
  826.                             red += xadd;
  827.                             green += xadd;
  828.                             blue += xadd;
  829.                         }
  830.                         pic->width = OScrn->Width;
  831.                         pic->height = OScrn->Height;
  832.                         FreeVec(p[0]);
  833.                        FreeVec(p[1]);
  834.                           FreeVec(p[2]);
  835.                         FreeScreen24(OScrn);
  836.                         pic->Opal = TRUE;
  837.                         CloseProgressWindow();
  838.                         return TRUE;
  839.                     }
  840.                     else {
  841.                         e = "Unable to allocate memory for bitmap";
  842.                         hnum = HE_AllocPlanes;
  843.                     }
  844.                 }
  845.                 else {
  846.                     if (ProgressWnd) {
  847.                          GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  848.                                              GTTX_Text,(ULONG)"Allocating Bitmap",
  849.                                             TAG_END);
  850.                         HandleProgressIDCMP();
  851.                     }
  852.                     pic->ilbm->Bmhd.nPlanes = min(TSMorphWnd->WScreen->BitMap.Depth,8);
  853.                     pic->ilbm->Bmhd.w = OScrn->Width;
  854.                     pic->ilbm->Bmhd.h = OScrn->Height;
  855.                     // Allocate BitMap
  856.                     if (InitArray(pic->ilbm->Bmhd.w) && (pic->ilbm->brbitmap = AllocMem(sizeof(struct BitMap),MEMF_CLEAR))) {
  857.                         InitBitMap(pic->ilbm->brbitmap,pic->ilbm->Bmhd.nPlanes,OScrn->Width,OScrn->Height);
  858.                         for (i=0;
  859.                             (i < pic->ilbm->Bmhd.nPlanes) && !e;            // Allow up to 8 bitplanes
  860.                             ++i) {
  861.                             if (!(pic->ilbm->brbitmap->Planes[i] = AllocRaster(pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h))) {
  862.                                 e = "Unable to allocate memory for bitmap";
  863.                                 hnum = HE_AllocPlanes;
  864.                             }
  865.                         }
  866.                     }
  867.                     else {
  868.                         e = "Unable to allocate memory for bitmap";
  869.                         hnum = HE_AllocPlanes;
  870.                     }
  871.                     // remap to screen palette and convert to planar - see above
  872.                     if (!e) {
  873.                         xadd = (((OScrn->Width+15)>>4)<<4) - OScrn->Width;
  874.                         red = p[0];
  875.                         blue = p[2];
  876.                         green = p[1];
  877.                         if (ProgressWnd) {
  878.                             GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  879.                                                    GTTX_Text,(ULONG)"Remapping OPAL palette",
  880.                                                   TAG_END);
  881.                             GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  882.                                                  GTSL_Level,0,
  883.                                                   GTSL_Max,OScrn->Height-1,TAG_END);
  884.                             HandleProgressIDCMP();
  885.                          }
  886.                         if (((struct ExecBase *)SysBase)->AttnFlags & AFF_68020) {
  887.                             RGBToScreen020(red,green,blue,OScrn->Height,OScrn->Width,maxcol,xadd,r,g,b);
  888.                         }
  889.                          else {
  890.                             RGBToScreen000(red,green,blue,OScrn->Height,OScrn->Width,maxcol,xadd,r,g,b);
  891.                         }
  892.                         if (ProgressWnd) {
  893.                              GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  894.                                                  GTTX_Text,(ULONG)"Converting to Planar",
  895.                                                 TAG_END);
  896.                             HandleProgressIDCMP();
  897.                         }
  898.                         if (!ChunkyToPlanar(pic,OScrn->Width,OScrn->Height,p[0])) {
  899.                             e = "Unable to allocate memory for bitmap";
  900.                             hnum = HE_AllocPlanes;
  901.                         }
  902.                         // Free everything and return
  903.                     }
  904.                     else {
  905.                         if (pic->ilbm->brbitmap) {
  906.                             for (i = 0;
  907.                                   (i < pic->ilbm->Bmhd.nPlanes);            // Allow up to 8 bitplanes
  908.                                   ++i) {
  909.                                 if (!(pic->ilbm->brbitmap->Planes[i])) {
  910.                                     FreeRaster(pic->ilbm->brbitmap->Planes[i],pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h);
  911.                                     pic->ilbm->brbitmap->Planes[i] = NULL;
  912.                                 }
  913.                             }
  914.                             FreeMem(pic->ilbm->brbitmap,sizeof(struct BitMap));
  915.                             pic->ilbm->brbitmap = NULL;
  916.                         }
  917.                     }
  918.                     FreeArray();
  919.                 }
  920.                 if (ProgressWnd) {
  921.                      GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  922.                                           GTTX_Text,(ULONG)"Cleaning up",
  923.                                          TAG_END);
  924.                     HandleProgressIDCMP();
  925.                 }
  926.                 if (p[0]) FreeVec(p[0]);
  927.                if (p[1]) FreeVec(p[1]);
  928.                   if (p[2]) FreeVec(p[2]);
  929.                 FreeScreen24(OScrn);
  930.                 if (!e) {
  931.                     pic->Opal = TRUE;
  932.                     CloseProgressWindow();
  933.                     return TRUE;
  934.                 }
  935.             }
  936.         }
  937.     }
  938.     else {
  939.         if (!e) {
  940.             e = "No opal.library";
  941.             hnum = HE_NoOpal;
  942.         }
  943.     }
  944.     // display error and return
  945.     Error(e,"OK",e1,hnum);
  946.     CloseProgressWindow();
  947.     return FALSE;
  948. }
  949.  
  950. extern struct RastPort     RP={0},            // Work Rast Ports
  951.                                  TRP={0};
  952. extern struct BitMap TBM={0};                // Temp bitmap
  953. extern UBYTE *plane0=NULL;                    // Planes for temporary bit maps
  954. extern UBYTE *plane1=NULL;
  955. extern UBYTE *plane2=NULL;
  956. extern UBYTE *plane3=NULL;
  957. extern UBYTE *plane4=NULL;
  958. extern UBYTE *plane5=NULL;
  959. extern UBYTE *plane6=NULL;
  960. extern UBYTE *plane7=NULL;
  961. extern UBYTE *Array=NULL;
  962.  
  963. /* Allocate and initialise things for image conversion
  964.  * w : width of image
  965.  */
  966. BOOL
  967. InitArray(UWORD w) {
  968.     if ((plane0 = AllocVec((((w+15)>>4)<<4),MEMF_CHIP)) &&
  969.           (plane1 = AllocVec((((w+15)>>4)<<4),MEMF_CHIP)) &&
  970.           (plane2 = AllocVec((((w+15)>>4)<<4),MEMF_CHIP)) &&
  971.           (plane3 = AllocVec((((w+15)>>4)<<4),MEMF_CHIP)) &&
  972.           (plane4 = AllocVec((((w+15)>>4)<<4),MEMF_CHIP)) &&
  973.           (plane5 = AllocVec((((w+15)>>4)<<4),MEMF_CHIP)) &&
  974.           (plane6 = AllocVec((((w+15)>>4)<<4),MEMF_CHIP)) &&
  975.           (plane7 = AllocVec((((w+15)>>4)<<4),MEMF_CHIP)) &&
  976.           (Array = AllocVec((((w+15)>>4)<<4),MEMF_CLEAR))) {
  977.          InitRastPort(&RP);
  978.       InitRastPort(&TRP);
  979.       InitBitMap(&TBM,8,w,1);
  980.       TRP.BitMap = &TBM;
  981.       TBM.Planes[0]=plane0;
  982.       TBM.Planes[1]=plane1;
  983.          TBM.Planes[2]=plane2;
  984.          TBM.Planes[3]=plane3;
  985.       TBM.Planes[4]=plane4;
  986.       TBM.Planes[5]=plane5;
  987.       TBM.Planes[6]=plane6;
  988.          TBM.Planes[7]=plane7;
  989.         return TRUE;
  990.     }
  991.     FreeArray();
  992.     return FALSE;
  993. }
  994.  
  995. /* Free everything allocated
  996.  * by InitArray()
  997.  */
  998. void
  999. FreeArray(void) {
  1000.      if (plane0) {
  1001.          FreeVec(plane0);
  1002.          plane0 = NULL;
  1003.      }
  1004.    if (plane1) {
  1005.        FreeVec(plane1);
  1006.        plane1 = NULL;
  1007.    }
  1008.    if (plane2) {
  1009.        FreeVec(plane2);
  1010.        plane2 = NULL;
  1011.    }
  1012.    if (plane3) {
  1013.        FreeVec(plane3);
  1014.        plane3 = NULL;
  1015.    }
  1016.    if (plane4) {
  1017.        FreeVec(plane4);
  1018.        plane4 = NULL;
  1019.    }
  1020.    if (plane5) {
  1021.        FreeVec(plane5);
  1022.        plane5 = NULL;
  1023.    }
  1024.    if (plane6) {
  1025.        FreeVec(plane6);
  1026.        plane6 = NULL;
  1027.    }
  1028.    if (plane7) {
  1029.        FreeVec(plane7);
  1030.        plane7 = NULL;
  1031.    }
  1032.    if (Array) {
  1033.        FreeVec(Array);
  1034.        Array = NULL;
  1035.    }
  1036. }
  1037.  
  1038. /* Convert Chunky 8 bit to planar
  1039.  * Always return true (historical)
  1040.  * pic    - picture pointer
  1041.  * w      - width
  1042.  * h      - height
  1043.  * chunky - chunky plane
  1044.  */
  1045. BOOL
  1046. ChunkyToPlanar(struct Picture *pic,UWORD w,UWORD h,UBYTE *chunky) {
  1047.       RP.BitMap = pic->ilbm->brbitmap;
  1048.      WritePixelArray8(&RP,0,0,w-1,h-1,chunky,&TRP);
  1049.      return TRUE;
  1050. }
  1051. /* Convert 24 bit chunky to RGB planar
  1052.  * Always return true (historical)
  1053.  * pic    - picture pointer
  1054.  * w      - width
  1055.  * h      - height
  1056.  * r,g,b  - chunky pointers
  1057.  */
  1058. BOOL
  1059. PlanarToChunky(struct Picture *pic,UWORD w,UWORD h,UBYTE *r,UBYTE *g,UBYTE *b) {
  1060.     struct BitMap         BM;
  1061.    InitBitMap(&BM,8,w,h);
  1062.       RP.BitMap = &BM;
  1063.    BM.Planes[0] = pic->ilbm->brbitmap->Planes[0];
  1064.    BM.Planes[1] = pic->ilbm->brbitmap->Planes[1];
  1065.    BM.Planes[2] = pic->ilbm->brbitmap->Planes[2];
  1066.    BM.Planes[3] = pic->ilbm->brbitmap->Planes[3];
  1067.    BM.Planes[4] = pic->ilbm->brbitmap->Planes[4];
  1068.    BM.Planes[5] = pic->ilbm->brbitmap->Planes[5];
  1069.    BM.Planes[6] = pic->ilbm->brbitmap->Planes[6];
  1070.    BM.Planes[7] = pic->ilbm->brbitmap->Planes[7];
  1071.    // Convert red to chunky
  1072.    ReadPixelArray8(&RP,0,0,w-1,h-1,r,&TRP);
  1073.    WaitBlit();
  1074.    BM.Planes[0] = pic->ilbm->brbitmap->Planes[8];
  1075.    BM.Planes[1] = pic->ilbm->brbitmap->Planes[9];
  1076.    BM.Planes[2] = pic->ilbm->brbitmap->Planes[10];
  1077.    BM.Planes[3] = pic->ilbm->brbitmap->Planes[11];
  1078.    BM.Planes[4] = pic->ilbm->brbitmap->Planes[12];
  1079.    BM.Planes[5] = pic->ilbm->brbitmap->Planes[13];
  1080.    BM.Planes[6] = pic->ilbm->brbitmap->Planes[14];
  1081.    BM.Planes[7] = pic->ilbm->brbitmap->Planes[15];
  1082.    // and green
  1083.    ReadPixelArray8(&RP,0,0,w-1,h-1,g,&TRP);
  1084.    WaitBlit();
  1085.    BM.Planes[0] = pic->ilbm->brbitmap->Planes[16];
  1086.    BM.Planes[1] = pic->ilbm->brbitmap->Planes[17];
  1087.    BM.Planes[2] = pic->ilbm->brbitmap->Planes[18];
  1088.    BM.Planes[3] = pic->ilbm->brbitmap->Planes[19];
  1089.    BM.Planes[4] = pic->ilbm->brbitmap->Planes[20];
  1090.    BM.Planes[5] = pic->ilbm->brbitmap->Planes[21];
  1091.    BM.Planes[6] = pic->ilbm->brbitmap->Planes[22];
  1092.    BM.Planes[7] = pic->ilbm->brbitmap->Planes[23];
  1093.    // and blue
  1094.    ReadPixelArray8(&RP,0,0,w-1,h-1,b,&TRP);
  1095.    WaitBlit();
  1096.    return TRUE;
  1097. }
  1098.  
  1099. /* RGB to screen palette
  1100.  * 68000/010 version
  1101.  * red,green,blue : chunky pointers - result is pallete mapped chunky in red
  1102.  * Height,Width   : image size
  1103.  * maxcol         : number of colours
  1104.  * xadd           : skip at end of line
  1105.  * r,g,b          : r,g,b palette
  1106.  */
  1107. void
  1108. RGBToScreen000(UBYTE *red,UBYTE *green,UBYTE *blue,UWORD Height,UWORD Width,
  1109.                           UWORD maxcol,UWORD xadd,UBYTE *r,UBYTE *g,UBYTE *b) {
  1110.     UWORD i,j,k;
  1111.     ULONG maxdiff;
  1112.     ULONG diff;
  1113.     LONG     t;
  1114.     UWORD index;
  1115.  
  1116.     // for each line
  1117.     for (j = 0;
  1118.           j < Height;
  1119.           ++j) {
  1120.         if (ProgressWnd) {
  1121.           GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  1122.                                      GTSL_Level,(ULONG)j,TAG_END);
  1123.             HandleProgressIDCMP();
  1124.        }
  1125.        // for each pixel
  1126.         for (i = 0;
  1127.               i < Width;
  1128.               ++i) {
  1129.             // Find closest color based on:
  1130.             // red_difference*sqrt(3)+green_difference*srqt(6)+blue_difference
  1131.             // (some sort of logic in the figures somewhere)
  1132.             maxdiff = 0x7FFFFFFF;
  1133.             for (k = 0;
  1134.                   k < maxcol;
  1135.                   ++k) {
  1136.                 t = *red - r[k];
  1137.                 diff = t*t*3;
  1138.                 t = *green - g[k];
  1139.                 diff += (t*t*6);
  1140.                 t = *blue - b[k];
  1141.                 diff += (t*t);
  1142.                 if (diff < maxdiff) {
  1143.                     maxdiff = diff;
  1144.                     index = k;
  1145.                 }
  1146.             }
  1147.             // Store index to color
  1148.             *red = index;
  1149.             ++red;
  1150.             ++green;
  1151.             ++blue;
  1152.         }
  1153.         red += xadd;
  1154.         green += xadd;
  1155.         blue += xadd;
  1156.         if (ProgressWnd) {
  1157.             HandleProgressIDCMP();
  1158.         }
  1159.     }
  1160. }
  1161.  
  1162. /* Palette to screen palette
  1163.  * 68000/010 version
  1164.  * Rp    : work rast port
  1165.  * pic   : picture pointer
  1166.  * maxcol: number of colours
  1167.  * r,g,b : r,g,b palette
  1168.  */
  1169. void
  1170. PaletteToScreen000(struct RastPort *Rp,struct Picture *pic,UWORD maxcol,
  1171.                                 UBYTE *r,UBYTE *g,UBYTE *b) {
  1172.     UWORD    i,j,k;            // loop counters
  1173.     LONG    penno;
  1174.     UBYTE    rr,gg,bb;
  1175.     ULONG maxdiff;
  1176.     ULONG diff;
  1177.     UWORD index;
  1178.     LONG    t;                    // temp diff
  1179.     UWORD EHB;
  1180.     BOOL isHAM6 = FALSE;
  1181.     BOOL isHAM8 = FALSE;
  1182.     BOOL isEHB = FALSE;
  1183.     struct DisplayInfo queryinfo;
  1184.     DisplayInfoHandle handle;
  1185.     struct BitMap         BM;
  1186.     UBYTE *arrayp;
  1187.     ULONG NewPen[256];
  1188.  
  1189.     // Initialise stuff
  1190.    InitBitMap(&BM,pic->ilbm->Bmhd.nPlanes,pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h);
  1191.       RP.BitMap = &BM;
  1192.    InitBitMap(&TBM,pic->ilbm->Bmhd.nPlanes,pic->ilbm->Bmhd.w,1);
  1193.    TRP.BitMap = &TBM;
  1194.    TBM.Planes[0]=plane0;
  1195.    TBM.Planes[1]=plane1;
  1196.    TBM.Planes[2]=plane2;
  1197.       TBM.Planes[3]=plane3;
  1198.    TBM.Planes[4]=plane4;
  1199.    TBM.Planes[5]=plane5;
  1200.    TBM.Planes[6]=plane6;
  1201.    TBM.Planes[7]=plane7;
  1202.  
  1203.     // based on CAMG chunk determine special type of image
  1204.     if ((handle = FindDisplayInfo(pic->ilbm->camg)) &&
  1205.          (GetDisplayInfoData(handle,(UBYTE *)&queryinfo,sizeof(queryinfo),DTAG_DISP,NULL))) {
  1206.         // 6 plane HAM
  1207.         if ((pic->ilbm->Bmhd.nPlanes == 6) && (queryinfo.PropertyFlags & DIPF_IS_HAM)) {
  1208.            GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  1209.                                      GTTX_Text,(ULONG)"Remapping HAM6 palette",
  1210.                                     TAG_END);
  1211.             isHAM6 = TRUE;
  1212.         }
  1213.         else {
  1214.             // 8 plane HAM
  1215.             if ((pic->ilbm->Bmhd.nPlanes == 8) && (queryinfo.PropertyFlags & DIPF_IS_HAM)) {
  1216.                 isHAM8 = TRUE;
  1217.                GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  1218.                                      GTTX_Text,(ULONG)"Remapping HAM8 palette",
  1219.                                     TAG_END);
  1220.             }
  1221.             else {
  1222.                 // 6 plane EHB
  1223.                   if ((pic->ilbm->Bmhd.nPlanes == 6) && (queryinfo.PropertyFlags & DIPF_IS_EXTRAHALFBRITE)) {
  1224.                       isEHB = TRUE;
  1225.                    GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  1226.                                                    GTTX_Text,(ULONG)"Remapping EHB palette",
  1227.                                                 TAG_END);
  1228.                   }
  1229.                   else {
  1230.                       // standard ILBM
  1231.                    GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  1232.                                               GTTX_Text,(ULONG)"Remapping ILBM palette",
  1233.                                             TAG_END);
  1234.                     for (i = 0;
  1235.                         (i < pic->ilbm->ncolors);
  1236.                         i++) {
  1237.                         maxdiff = 0x7FFFFFFF;
  1238.                         for (k = 0;
  1239.                               k < maxcol;
  1240.                               ++k) {
  1241.                             t = pic->ilbm->RGB[i*4+1] - r[k];
  1242.                             diff = t*t*3;
  1243.                             t = pic->ilbm->RGB[i*4+2] - g[k];
  1244.                             diff += (t*t*6);
  1245.                             t = pic->ilbm->RGB[i*4+3] - b[k];
  1246.                             diff += (t*t);
  1247.                             if (diff < maxdiff) {
  1248.                                 maxdiff = diff;
  1249.                                 NewPen[i] = k;
  1250.                             }
  1251.                         }
  1252.                     }
  1253.                   }
  1254.             }
  1255.         }
  1256.     }
  1257.     // for each line
  1258.     for (j = 0;
  1259.          j < pic->ilbm->Bmhd.h;
  1260.          ++j) {
  1261.         if (ProgressWnd) {
  1262.           GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  1263.                               GTSL_Level,(ULONG)j,TAG_END);
  1264.             HandleProgressIDCMP();
  1265.           }
  1266.           // convert line to chunky
  1267.           ReadPixelLine8(Rp,0,j,pic->ilbm->Bmhd.w,Array,&TRP);
  1268.           arrayp = Array;
  1269.           // for each pixel depending on mode convert line to screen palette (like palette to screen)
  1270.         if (isHAM6) {
  1271.             // rgb = 0 at start of line
  1272.               rr = gg = bb = 0;
  1273.            for (i = 0;
  1274.                     i < pic->ilbm->Bmhd.w;
  1275.                  ++i) {
  1276.                penno = *arrayp;
  1277.                switch (penno & 0x30) {    // HAM selection
  1278.                case 0:
  1279.                    rr = pic->ilbm->RGB[penno*4+1];
  1280.                    gg = pic->ilbm->RGB[penno*4+2];
  1281.                    bb = pic->ilbm->RGB[penno*4+3];
  1282.                    break;
  1283.                case 0x10:
  1284.                    bb = (penno&0xf)|((penno&0xf)<<4);
  1285.                    break;
  1286.                case 0x20:
  1287.                    rr = (penno&0xf)|((penno&0xf)<<4);
  1288.                    break;
  1289.                case 0x30:
  1290.                    gg = (penno&0xf)|((penno&0xf)<<4);
  1291.                    break;
  1292.                }
  1293.                 // Find closest color
  1294.                 maxdiff = 0x7FFFFFFF;
  1295.                 for (k = 0;
  1296.                       k < maxcol;
  1297.                       ++k) {
  1298.                     t = rr - r[k];
  1299.                     diff = t*t*3;
  1300.                     t = gg - g[k];
  1301.                     diff += (t*t*6);
  1302.                     t = bb - b[k];
  1303.                     diff += (t*t);
  1304.                     if (diff < maxdiff) {
  1305.                         maxdiff = diff;
  1306.                         index = k;
  1307.                     }
  1308.                 }
  1309.                 *arrayp++ = index;
  1310.             }
  1311.           }
  1312.           else {
  1313.               if (isHAM8) {
  1314.                   // very similar to HAM6
  1315.                 rr = gg = bb = 0;
  1316.                for (i = 0;
  1317.                         i < pic->ilbm->Bmhd.w;
  1318.                      ++i) {
  1319.                    penno = *arrayp;
  1320.                    switch (penno & 0xc0) {
  1321.                    case 0:
  1322.                        rr = pic->ilbm->RGB[penno*4+1];
  1323.                        gg = pic->ilbm->RGB[penno*4+2];
  1324.                        bb = pic->ilbm->RGB[penno*4+3];
  1325.                        break;
  1326.                    case 0x40:
  1327.                        bb = (penno&0x3f)<<2;
  1328.                        break;
  1329.                    case 0x80:
  1330.                        rr = (penno&0x3f)<<2;
  1331.                        break;
  1332.                    case 0xc0:
  1333.                        gg = (penno&0x3f)<<2;
  1334.                        break;
  1335.                    }
  1336.                     // Find closest color
  1337.                     maxdiff = 0x7FFFFFFF;
  1338.                     for (k = 0;
  1339.                           k < maxcol;
  1340.                           ++k) {
  1341.                         t = rr - r[k];
  1342.                         diff = t*t*3;
  1343.                         t = gg - g[k];
  1344.                         diff += (t*t*6);
  1345.                         t = bb - b[k];
  1346.                         diff += (t*t);
  1347.                         if (diff < maxdiff) {
  1348.                             maxdiff = diff;
  1349.                             index = k;
  1350.                         }
  1351.                     }
  1352.                     *arrayp++ = index;
  1353.                 }
  1354.               }
  1355.               else {
  1356.                   if (isEHB) {
  1357.                       // simple - just check highest plane and divide by two if required
  1358.                    for (i = 0;
  1359.                             i < pic->ilbm->Bmhd.w;
  1360.                          ++i) {
  1361.                        penno = *arrayp;
  1362.                        EHB = (penno & 0x20)?1:0;
  1363.                        penno &= 0x1f;
  1364.                        rr = pic->ilbm->RGB[penno*4+1]>>EHB;
  1365.                        gg = pic->ilbm->RGB[penno*4+2]>>EHB;
  1366.                        bb = pic->ilbm->RGB[penno*4+3]>>EHB;
  1367.                         // Find closest color
  1368.                         maxdiff = 0x7FFFFFFF;
  1369.                         for (k = 0;
  1370.                               k < maxcol;
  1371.                               ++k) {
  1372.                             t = rr - r[k];
  1373.                             diff = t*t*3;
  1374.                             t = gg - g[k];
  1375.                             diff += (t*t*6);
  1376.                             t = bb - b[k];
  1377.                             diff += (t*t);
  1378.                             if (diff < maxdiff) {
  1379.                                 maxdiff = diff;
  1380.                                 index = k;
  1381.                             }
  1382.                         }
  1383.                         *arrayp++ = index;
  1384.                     }
  1385.                   }
  1386.                   else {
  1387.                       // simple palette remap
  1388.                    for (i = 0;
  1389.                             i < pic->ilbm->Bmhd.w;
  1390.                          ++i) {
  1391.                        penno = *arrayp;
  1392.                         *arrayp++ = NewPen[penno];
  1393.                     }
  1394.                 }
  1395.             }
  1396.        }
  1397.        // Convert line from chunky palette to planar
  1398.        WritePixelLine8(Rp,0,j,pic->ilbm->Bmhd.w,Array,&TRP);
  1399.     }
  1400. }
  1401.  
  1402. void
  1403. PaletteToEGS000(struct RastPort *Rp,struct Picture *pic,UBYTE *plane,UBYTE *r,UBYTE *g,UBYTE *b) {
  1404.     UWORD    i,j;            // loop counters
  1405.     LONG    penno;
  1406.     UBYTE    rr,gg,bb;
  1407.     UWORD EHB;
  1408.     BOOL isHAM6 = FALSE;
  1409.     BOOL isHAM8 = FALSE;
  1410.     BOOL isEHB = FALSE;
  1411.     struct DisplayInfo queryinfo;
  1412.     DisplayInfoHandle handle;
  1413.     struct BitMap         BM;
  1414.     UBYTE *arrayp;
  1415.  
  1416.     // Initialise stuff
  1417.    InitBitMap(&BM,pic->ilbm->Bmhd.nPlanes,pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h);
  1418.       RP.BitMap = &BM;
  1419.    InitBitMap(&TBM,pic->ilbm->Bmhd.nPlanes,pic->ilbm->Bmhd.w,1);
  1420.    TRP.BitMap = &TBM;
  1421.    TBM.Planes[0]=plane0;
  1422.    TBM.Planes[1]=plane1;
  1423.    TBM.Planes[2]=plane2;
  1424.       TBM.Planes[3]=plane3;
  1425.    TBM.Planes[4]=plane4;
  1426.    TBM.Planes[5]=plane5;
  1427.    TBM.Planes[6]=plane6;
  1428.    TBM.Planes[7]=plane7;
  1429.  
  1430.     // based on CAMG chunk determine special type of image
  1431.     if ((handle = FindDisplayInfo(pic->ilbm->camg)) &&
  1432.          (GetDisplayInfoData(handle,(UBYTE *)&queryinfo,sizeof(queryinfo),DTAG_DISP,NULL))) {
  1433.         // 6 plane HAM
  1434.         if ((pic->ilbm->Bmhd.nPlanes == 6) && (queryinfo.PropertyFlags & DIPF_IS_HAM)) {
  1435.            GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  1436.                                      GTTX_Text,(ULONG)"Converting HAM6 to EGS",
  1437.                                     TAG_END);
  1438.             isHAM6 = TRUE;
  1439.         }
  1440.         else {
  1441.             // 8 plane HAM
  1442.             if ((pic->ilbm->Bmhd.nPlanes == 8) && (queryinfo.PropertyFlags & DIPF_IS_HAM)) {
  1443.                 isHAM8 = TRUE;
  1444.                GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  1445.                                      GTTX_Text,(ULONG)"Converting HAM8 to EGS",
  1446.                                     TAG_END);
  1447.             }
  1448.             else {
  1449.                 // 6 plane EHB
  1450.                   if ((pic->ilbm->Bmhd.nPlanes == 6) && (queryinfo.PropertyFlags & DIPF_IS_EXTRAHALFBRITE)) {
  1451.                       isEHB = TRUE;
  1452.                    GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  1453.                                                    GTTX_Text,(ULONG)"Converting EHB to EGS",
  1454.                                                 TAG_END);
  1455.                   }
  1456.                   else {
  1457.                       // standard ILBM
  1458.                    GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
  1459.                                               GTTX_Text,(ULONG)"Converting ILBM to EGS",
  1460.                                             TAG_END);
  1461.                   }
  1462.             }
  1463.         }
  1464.     }
  1465.     // for each line
  1466.     for (j = 0;
  1467.          j < pic->ilbm->Bmhd.h;
  1468.          ++j) {
  1469.         if (ProgressWnd) {
  1470.           GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
  1471.                               GTSL_Level,(ULONG)j,TAG_END);
  1472.             HandleProgressIDCMP();
  1473.           }
  1474.           // convert line to chunky
  1475.           ReadPixelLine8(Rp,0,j,pic->ilbm->Bmhd.w,Array,&TRP);
  1476.           arrayp = Array;
  1477.           // for each pixel depending on mode convert to EGS
  1478.         if (isHAM6) {
  1479.             // rgb = 0 at start of line
  1480.               rr = gg = bb = 0;
  1481.            for (i = 0;
  1482.                     i < pic->ilbm->Bmhd.w;
  1483.                  ++i) {
  1484.                penno = *arrayp;
  1485.                switch (penno & 0x30) {    // HAM selection
  1486.                case 0:
  1487.                    rr = pic->ilbm->RGB[penno*4+1];
  1488.                    gg = pic->ilbm->RGB[penno*4+2];
  1489.                    bb = pic->ilbm->RGB[penno*4+3];
  1490.                    break;
  1491.                case 0x10:
  1492.                    bb = (penno&0xf)|((penno&0xf)<<4);
  1493.                    break;
  1494.                case 0x20:
  1495.                    rr = (penno&0xf)|((penno&0xf)<<4);
  1496.                    break;
  1497.                case 0x30:
  1498.                    gg = (penno&0xf)|((penno&0xf)<<4);
  1499.                    break;
  1500.                }
  1501.                *plane++ = rr;
  1502.                *plane++ = gg;
  1503.                *plane++ = bb;
  1504.                plane++;
  1505.                arrayp++;
  1506.             }
  1507.           }
  1508.           else {
  1509.               if (isHAM8) {
  1510.                   // very similar to HAM6
  1511.                 rr = gg = bb = 0;
  1512.                for (i = 0;
  1513.                         i < pic->ilbm->Bmhd.w;
  1514.                      ++i) {
  1515.                    penno = *arrayp;
  1516.                    switch (penno & 0xc0) {
  1517.                    case 0:
  1518.                        rr = pic->ilbm->RGB[penno*4+1];
  1519.                        gg = pic->ilbm->RGB[penno*4+2];
  1520.                        bb = pic->ilbm->RGB[penno*4+3];
  1521.                        break;
  1522.                    case 0x40:
  1523.                        bb = (penno&0x3f)<<2;
  1524.                        break;
  1525.                    case 0x80:
  1526.                        rr = (penno&0x3f)<<2;
  1527.                        break;
  1528.                    case 0xc0:
  1529.                        gg = (penno&0x3f)<<2;
  1530.                        break;
  1531.                    }
  1532.                    *plane++ = rr;
  1533.                    *plane++ = gg;
  1534.                    *plane++ = bb;
  1535.                    plane++;
  1536.                    arrayp++;
  1537.                 }
  1538.               }
  1539.               else {
  1540.                   if (isEHB) {
  1541.                       // simple - just check highest plane and divide by two if required
  1542.                    for (i = 0;
  1543.                             i < pic->ilbm->Bmhd.w;
  1544.                          ++i) {
  1545.                        penno = *arrayp;
  1546.                        EHB = (penno & 0x20)?1:0;
  1547.                        penno &= 0x1f;
  1548.                        rr = pic->ilbm->RGB[penno*4+1]>>EHB;
  1549.                        gg = pic->ilbm->RGB[penno*4+2]>>EHB;
  1550.                        bb = pic->ilbm->RGB[penno*4+3]>>EHB;
  1551.                        *plane++ = rr;
  1552.                        *plane++ = gg;
  1553.                        *plane++ = bb;
  1554.                        plane++;
  1555.                        arrayp++;
  1556.                     }
  1557.                   }
  1558.                   else {
  1559.                       // simple palette remap
  1560.                    for (i = 0;
  1561.                             i < pic->ilbm->Bmhd.w;
  1562.                          ++i) {
  1563.                        penno = *arrayp;
  1564.                        rr = pic->ilbm->RGB[penno*4+1];
  1565.                        gg = pic->ilbm->RGB[penno*4+2];
  1566.                        bb = pic->ilbm->RGB[penno*4+3];
  1567.                        *plane++ = rr;
  1568.                        *plane++ = gg;
  1569.                        *plane++ = bb;
  1570.                        plane++;
  1571.                        arrayp++;
  1572.                     }
  1573.                 }
  1574.             }
  1575.        }
  1576.         plane += (pic->EGS_BitMap->BytesPerRow - (4*pic->ilbm->Bmhd.w));
  1577.     }
  1578. }
  1579.